package com.lvmama.autoconfig;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.lamama.util.StringTools;
import com.lvmama.entity.system.BasePair;
import com.lvmama.entity.system.Config;
import com.lvmama.system.service.ConfigService;


/**
 * 
* @ClassName: ConfigManager 
* @Description: TODO 参数配置管理类
* @date 2017年2月8日 下午2:19:07
 */
@Component
public class ConfigManager
{
	Logger logger = Logger.getLogger(ConfigManager.class);
	
	@Autowired
	private ConfigService configService;
	
	@SuppressWarnings("unused")
	private static ConfigManager configManager;

	private List<Config> allConfig = new ArrayList<Config>();
	
	 /**
     * 配置项的容器.
     */
    private Map<String,BasePair<List<Config>,String[]>> paramMap = new HashMap<String,BasePair<List<Config>,String[]>>();
    
    /**
     * 配置索引
     */
    private Map<String,TreeSet<String>> idx_configname = new HashMap<String,TreeSet<String>>();
	
	public void init(String syscode)
	{
		logger.info("加载参数开始！");
		Map<String,BasePair<List<Config>,String[]>> tmpMap=new HashMap<String,BasePair<List<Config>,String[]>>();
		Map<String,TreeSet<String>> tmp_idx_configname = new HashMap<String,TreeSet<String>>();

		Map<String,String> param = new HashMap<String,String>();
		param.put("syscode", syscode);
		//List<Config> list=configService.queryConfig(param);
		List<Config> list = configService.queryAllConfig();

		int configCount=0;
		String lastSysCode=null;
		String key=null;
		String lastKey=null;
		List<Config> valueList=new ArrayList<Config>();
		TreeSet<String> nameSet=null;;
		BasePair<List<Config>,String[]> bp=null;
		String[] strs=null;
		Config invo=null;
		for(Config vo:list){
			key=vo.getConfigname()+"|"+vo.getParamname();//存储方式的缘故,ConfigName中不能出现"|"
			if(vo.getParamvalue()==null) vo.setParamvalue("");//特殊处理,谨防空指针
			if(lastKey==null){
				valueList.add(vo);
                lastSysCode=vo.getSyscode();
			}else if(lastKey.equals(key)){
				if(StringTools.equals(vo.getSyscode(), lastSysCode)){
					addStrListPlus(valueList,vo);
				}else if(!"PUBLIC".equals(vo.getSyscode())){
					valueList.clear();
					addStrListPlus(valueList,vo);
                    lastSysCode=vo.getSyscode();
				}
			}else{
				strs=new String[valueList.size()];
				for(int i=0;i<valueList.size();i++){
					invo=valueList.get(i);
					strs[i]=invo.getParamvalue();
					if((nameSet=tmp_idx_configname.get(invo.getConfigname()))!=null){
						nameSet.add(invo.getParamname());
					}else{
						nameSet=new TreeSet<String>(new AlphaComp());
						nameSet.add(invo.getParamname());
						tmp_idx_configname.put(invo.getConfigname(), nameSet);
					}
				}
				bp=new BasePair<List<Config>,String[]>(valueList,strs);
				tmpMap.put(lastKey, bp);
				configCount+=valueList.size();
				valueList=new ArrayList<Config>();
				addStrListPlus(valueList,vo);
                lastSysCode=vo.getSyscode();
			}
			lastKey=key;
		}
		if(valueList.size()>0){
			strs=new String[valueList.size()];
			for(int i=0;i<valueList.size();i++){
				invo=valueList.get(i);
				strs[i]=invo.getParamvalue();
				if((nameSet=tmp_idx_configname.get(invo.getConfigname()))!=null){
					nameSet.add(invo.getParamname());
				}else{
					nameSet=new TreeSet<String>(new AlphaComp());
					nameSet.add(invo.getParamname());
					tmp_idx_configname.put(invo.getConfigname(), nameSet);
				}
			}
			bp=new BasePair<List<Config>,String[]>(valueList,strs);
			tmpMap.put(lastKey, bp);
			configCount+=valueList.size();
		}
		paramMap=tmpMap;
		idx_configname=tmp_idx_configname;
		allConfig = list;
		logger.info("加载参数结束！加载参数条数："+configCount);
		
	}
	
	/**
     * 将字符串加入到list
     * @param list List
     * @param str 加入list的字符串
     * @return boolean,add时true,join时false
     */
    public boolean addStrListPlus(List<Config> list,Config vo){
    	StringBuffer sb=new StringBuffer();
    	boolean isAdd=true;
    	
    	if(list==null){
    		isAdd=false;
    	}else if(list.size()==0){
    		list.add(vo);
    	}else{
    		Config lastVo=list.get(list.size()-1);
    		String str=vo.getParamvalue();
    		String lastStr=lastVo.getParamvalue();
    		if(lastStr!=null&&str!=null&&lastStr.endsWith("-->")&&str.startsWith("<--")){
    			sb.append(lastStr).append(str).delete(lastStr.length()-3,lastStr.length()+3);
    			lastVo.setParamvalue(sb.toString());
    			sb.delete(0, sb.length());
    			isAdd=false;
    		}else{
    			list.add(vo);
    		}
    	}
    	return isAdd;
    }
    
    public class AlphaComp implements Comparator<String>
    {

        public int compare(String s1, String s2) {
            s1 = s1.toLowerCase();
            s2 = s2.toLowerCase();
            return s1.compareTo(s2);
        }
        
    }
    
    /**
     * 此方法放回由configName和paramName确定的配置项参数的第一个值
     * 注意如果配置项配置了多个参数,返回第一个值.
     * @param configName 配置项名字
     * @param paramName 配置项的参数名
     * @return 返回的配置参数的值.如果查找相应的失败返回""
     */
    public String getParamValue(String configName, String paramName) {
    	Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
    	BasePair<List<Config>,String[]> bp=tmpMap.get(configName+"|"+paramName);
        if (bp == null||bp.getValue2().length==0){
            return "";
        }
    	return bp.getValue2()[0];
    }
    
    /**
     * 此方法放回由configName和paramName确定的配置项参数的第一个值
     * 注意如果配置项配置了多个参数,返回第一个值.如果没有配置则返回默认值
     * @param configName 配置项名字
     * @param paramName 配置项的参数名
     * @param defalt 默认值
     * @return
     */
    public String getParamValue(String configName, String paramName,String defalt) {
		return StringTools.nvl(getParamValue(configName, paramName),defalt);
    }
    
    /**
     * 此方法放回由configName和paramName确定的配置项参数的第一个ConfigVo
     * @param configName 配置项名字
     * @param paramName 配置项的参数名
     * @return
     */
    public Config getConfigVo(String configName, String paramName){
    	Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
    	BasePair<List<Config>,String[]> bp=tmpMap.get(configName+"|"+paramName);
        if (bp == null||bp.getValue1().size()==0){
            return null;
        }
    	return bp.getValue1().get(0);
    }
    
    /**
     * 此方法放回由configName和paramName确定的配置项参数的所有值
     * @param configName 配置项名字
     * @param paramName 配置项的参数名
     * @return String[] 返回配置参数的所有值,如果查询失败则返回0长度的String[]
     */
    public String[] getParamValues(String configName, String paramName) {
    	Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
    	BasePair<List<Config>,String[]> bp=tmpMap.get(configName+"|"+paramName);
        if (bp == null){
            return new String[0];
        }else{
        	return bp.getValue2();
        }
    }
    
    /**
     * 此方法放回由configName和paramName确定的配置项参数的所有ConfigVo
     * @param configName 配置项名字
     * @param paramName 配置项的参数名
     * @return
     */
    public List<Config> getConfigVoList(String configName, String paramName){
    	Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
    	BasePair<List<Config>,String[]> bp=tmpMap.get(configName+"|"+paramName);
        if (bp == null){
            return null;
        }
    	return bp.getValue1();
    }
    
    /**
     * 返回指定配置项的所有配置参数名
     * @param configName 配置项
     * @return 有配置参数名，如果查询失败则返回0长度的String[]
     */
	public String[] getParamNamesByConfigName(String configName) {
		Map<String,TreeSet<String>> tmpMap=idx_configname;
		TreeSet<String> set=tmpMap.get(configName);
		if(set==null){
			return new String[0];
		}else{
			return set.toArray(new String[0]);
		}
    }
    
    /**
     * 返回指定配置项的所有配置参数值
     * @param configName 配置项
     * @return 有配置参数值,如果查询失败则返回0长度的String[][]
     */
	public String[][] getParamValuesByConfigName(String configName) {
		Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
		String[] strs=getParamNamesByConfigName(configName);
		String[][] rtnValues = new String[strs.length][0];
		BasePair<List<Config>,String[]> bp=null;
		for(int i=0;i<strs.length;i++){
			if((bp=tmpMap.get(configName+"|"+strs[i]))!=null){
				rtnValues[i]=bp.getValue2();
			}
		}
        return rtnValues;
    }
      
    /**
     * 打印所有的参数配置项信息
     * @return String 配置信息字符串
     */
    public String showAllParams() {
		Map<String,BasePair<List<Config>,String[]>> tmpMap=paramMap;
        Set<String> keySet = tmpMap.keySet();
        Iterator<String> it = keySet.iterator();
        StringBuffer sb = new StringBuffer();
        String key = null;
        String[] paramValues = null;
        
        while (it.hasNext()){
        	key = (String) it.next();
        	paramValues=(String[])tmpMap.get(key).getValue2();
        	sb.append(key).append("=");
        	for(int i=0;i<paramValues.length;i++){
        		sb.append("<").append(paramValues[i]).append(">");
        	}
        	if(it.hasNext()) sb.append("\n");
        }
        return sb.toString();
    }

	public List<Config> showAllConfig(){
		return allConfig;
	}
}
